import 'dart:io';
import 'dart:isolate';
import 'dart:ui';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_downloader/flutter_downloader.dart';
import 'package:jyofservice/util/APPUpgrade.dart';
import 'package:jyofservice/util/webconfig.dart';
import 'package:open_file/open_file.dart';
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:progress_dialog_null_safe/progress_dialog_null_safe.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:url_launcher/url_launcher.dart';

class UpdatePage extends StatefulWidget {
  final Widget child;

  const UpdatePage(this.child);

  @override
  _UpdatePageState createState() => _UpdatePageState();
}

class _UpdatePageState extends State<UpdatePage> {
  SharedPreferences? sharedPreferences;
  String? _localPath;
  String? downloadUrl;
  late ProgressDialog pr;
  ReceivePort _port = ReceivePort();
  late String path;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    _bindBackgroundIsolate();
    FlutterDownloader.registerCallback(downloadCallback);
    _checkPermission().then((onvalue) {
      print('haha:' + onvalue.toString());
      AppUpgrade().getNewVersionApp(context).then((value) {
        if (value["upgrade"]) {
          showDialog(
              context: context,
              barrierDismissible: false,
              builder: (BuildContext context) {
                return CupertinoAlertDialog(
                  title: Text("是否更新"),
                  content: Text(
                    "检测到新版本",
                    style: Theme.of(context)
                        .textTheme
                        .titleMedium!
                        .copyWith(
                        color: Theme.of(context)
                            .textTheme
                            .bodySmall!
                            .color),
                  ),
                  actions: <Widget>[
                    CupertinoDialogAction(
                      child: const Text('下次再说'),
                      onPressed: () {
                        Navigator.pop(context, false);
                      },
                    ),
                    CupertinoDialogAction(
                      child: const Text('立即更新'),
                      onPressed: () {
                        Navigator.pop(context, false);
                        if (Platform.isIOS) {
                          _launchAppStore(
                              WebConfig().ITUNSTORE);
                        } else {
                          downloadUrl = value["url"];
                          _downloadApp(context);
                        }
                      },
                    )
                  ],
                );
              });
        }
      });
    });
  }

  void _unbindBackgroundIsolate() {
    IsolateNameServer.removePortNameMapping('downloader_send_port');
  }

  void _bindBackgroundIsolate() {
    bool isSuccess = IsolateNameServer.registerPortWithName(
        _port.sendPort, 'downloader_send_port');
    if (!isSuccess) {
      _unbindBackgroundIsolate();
      _bindBackgroundIsolate();
      return;
    }
    _port.listen((dynamic data) {
      final id = (data as List<dynamic>)[0] as String;
      final value = data[1];
      final progress = data[2] as int;

      final status;
      switch (value) {
        case 0:
          status = DownloadTaskStatus.undefined;
          break;
        case 1:
          status =  DownloadTaskStatus.enqueued;
          break;
        case 2:
          status =  DownloadTaskStatus.running;
          break;
        case 3:
          status =  DownloadTaskStatus.complete;
          break;
        case 4:
          status =  DownloadTaskStatus.failed;
          break;
        case 5:
          status =  DownloadTaskStatus.canceled;
          break;
        case 6:
          status = DownloadTaskStatus.paused;
          break;
        default:
          throw ArgumentError('Invalid value: $value');
      }

      if (status == DownloadTaskStatus.running) {
        pr.update(progress: progress.toDouble(), message: "正在更新版本，请等待…");
      }
      if (status == DownloadTaskStatus.failed) {
        if (pr.isShowing()) {
          pr.hide();
        }
      }
      if (status == DownloadTaskStatus.complete) {
        if (pr.isShowing()) {
          pr.hide();
        }
        OpenFile.open(path + "/" + WebConfig().APKNAME);
       FlutterDownloader.open(taskId: id);
      }
    });
  }

  @override
  Widget build(BuildContext context) => widget.child;

  //检查权限
  Future<bool> _checkPermission() async {
    if (Platform.isAndroid) {
      // PermissionStatus permission = await PermissionHandler()
      //     .checkPermissionStatus(PermissionGroup.storage);
      if (await Permission.storage.request().isGranted) {
        return true;
      } else {
        Map<Permission, PermissionStatus> statuses = await [
          Permission.storage,
        ].request();
        if (statuses[Permission.storage] == PermissionStatus.granted) {
          return true;
        }

      }
    } else {
      return true;
    }
    return false;
  }


  _launchAppStore(url) async {
    if (await canLaunch(url)) {
      await launch(url);
    } else {
      throw 'Could not launch $url';
    }
  }

// 获取安装地址
  Future<String?> _apkLocalPath() async {
    final directory = await (getExternalStorageDirectory());
    _localPath = directory?.path.toString();
    return _localPath;
  }

  Future _downloadApp(BuildContext context) async {
    print("haha");
    pr = ProgressDialog(context, type: ProgressDialogType.download);
    pr.style(
      message: "下载中...",
      maxProgress: 100.0

    );
    if (!pr.isShowing()) {
      pr.show();
    }
    path = (await _apkLocalPath())! + '/Download';
    final saveDir = Directory(path);
    bool hasExisted = await saveDir.exists();
    if (!hasExisted) {
      saveDir.create();
    }
    FlutterDownloader.cancelAll();
    //下载
    final tastId = await FlutterDownloader.enqueue(
        url: downloadUrl!,
        fileName: WebConfig().APKNAME,
        savedDir: path,
        showNotification: true,
        openFileFromNotification: true);
  }

  @pragma('vm:entry-point')
  static void downloadCallback(id, status, progress) {
    print('Download task ($id) is in status ($status) and process ($progress)');

    final SendPort send =
    IsolateNameServer.lookupPortByName('downloader_send_port')!;
    send.send([id, status, progress]);
  }

  @override
  void dispose() {
    IsolateNameServer.removePortNameMapping('downloader_send_port');
    super.dispose();
  }
}
